﻿// Spun AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

function scalarUpdate(id, value) {
    $(id).innerHTML=value;
}

/* Actions */

function ActionCallback(transport, controller, method) {
    var action="Action '" + method + "' on '" + controller + "'";

    if(transport.responseJSON != null) {
        var Response=transport.responseJSON;
        
        if(Response.Success == false) {
            if(Response.ExceptionSummary != null) {
                alert(action + ' caused server-side exception: ' + Response.ExceptionSummary.Message);
            } else {
                alert(action + ' failed');
            }
        }
    } else {
        if(transport.status != 200) {
            alert(action + ' failed with HTTP status ' + transport.status);
        }
    }
}

function Action(controller, method, argument) {
    var Url= 'action/' + controller + '/' + method + '.action';
    
    if(argument) {
        Url = Url + '?arg=' + Object.toJSON(argument);
    }
    
    new Ajax.Request(Url, { 
        method: 'get', 
        onFailure: function(transport) { ActionCallback(transport, controller, method); },
        onSuccess: function(transport) { ActionCallback(transport, controller, method); }
    });
}

/* Onload binding */

var Registration = Class.create({
    initialize: function(id, path, updateMethod) {
        this.updateMethod=updateMethod;
        this.id=id;
        this.path=path;
    },
    
    update: function(value) {
        this.updateMethod(this.id, value);
    },
    
    invalidate: function(value) {
        this.updateMethod(this.id, null);
    }
});

var RegisteredViews=[];
function register(ID, path, updateMethod) {
    RegisteredViews[RegisteredViews.length]=new Registration(ID, path, updateMethod);
}

function bindRegisteredViews() {
    var Request = {BindingPaths: []};
    
    for(var i=0; i < RegisteredViews.length; i++) {
        Request.BindingPaths[i]=RegisteredViews[i].path;
    }
    
    Action('binding', 'bind', Request);
}

/* Polling */

function ProcessUpdates(ReturnValue) {
    if(ReturnValue == null)
        return;
        
    var Updates=ReturnValue['Updates'];
    
    if(Updates == null)
        return;
        
    for(var i=0; i<Updates.length; i++) {
        var Update=Updates[i];
        
        for(var i=0; i < RegisteredViews.length; i++) {
            var View=RegisteredViews[i];
            
            if(Update.Valid)
                View.update(Update.Object);
            else
                View.invalidate(null);
        }
    }
}

function PollingCallback(transport) {
    if(transport.status != 200) {
        alert('Connection to server lost - status ' + transport.status);
    } else {
        var Timeout=10000;
        
        var Response=transport.responseJSON;
        
        if(Response != null) {
            if(Response.Success == false) {
                if(Response.ExceptionSummary != null) {
                    alert('Server-side exception caused by polling: ' + Response.ExceptionSummary.Message);
                } else {
                    alert('Polling failed');
                }
            } else {
                Timeout=100;
                ProcessUpdates(Response.ReturnValue);
            }
        } 
           
        setTimeout('Poll();', Timeout);
    } 
} 

function Poll() {
    new Ajax.Request('polling', { 
        method: 'get', 
        onFailure: PollingCallback,
        onSuccess: PollingCallback
    });
}

function StartSpun() {
    bindRegisteredViews();
    Poll();
}